﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.Rendering.BatchRendererGroup
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
using UnityEngine.Bindings;
using UnityEngine.Scripting;

#nullable disable
namespace UnityEngine.Rendering
{
  /// <summary>
  ///   <para>A group of batches.</para>
  /// </summary>
  [RequiredByNativeCode]
  [NativeHeader("Runtime/Camera/BatchRendererGroup.h")]
  [NativeHeader("Runtime/Math/Matrix4x4.h")]
  [StructLayout(LayoutKind.Sequential)]
  public class BatchRendererGroup : IDisposable
  {
    private IntPtr m_GroupHandle = IntPtr.Zero;
    private BatchRendererGroup.OnPerformCulling m_PerformCulling;

    public BatchRendererGroup(
      BatchRendererGroup.OnPerformCulling cullingCallback)
    {
      this.m_PerformCulling = cullingCallback;
      this.m_GroupHandle = BatchRendererGroup.Create(this);
    }

    /// <summary>
    ///   <para>Deletes a group.</para>
    /// </summary>
    public void Dispose()
    {
      BatchRendererGroup.Destroy(this.m_GroupHandle);
      this.m_GroupHandle = IntPtr.Zero;
    }

    /// <summary>
    ///   <para>Adds a new batch to the group.</para>
    /// </summary>
    /// <param name="mesh">The Mesh to draw.</param>
    /// <param name="subMeshIndex">Specifies which subset of the mesh to draw. This applies only to meshes that are composed of several materials.</param>
    /// <param name="material">Material to use.</param>
    /// <param name="layer"> to use.</param>
    /// <param name="castShadows">Whether the meshes cast shadows.</param>
    /// <param name="receiveShadows">Whether the meshes receive shadows.</param>
    /// <param name="invertCulling">Specify whether to invert the backface culling (true) or not (false). This flag can "flip" the culling mode of all rendered objects. Major use case: rendering reflections for mirrors, water etc. Since virtual camera for rendering the reflection is mirrored, the culling order has to be inverted. You can see how the Water script in Effects standard package does that.</param>
    /// <param name="bounds">Bounds to use. Should specify the combined bounds of all the instances.</param>
    /// <param name="instanceCount">The number of instances to draw.</param>
    /// <param name="customProps">Additional material properties to apply. See MaterialPropertyBlock.</param>
    /// <param name="associatedSceneObject">The GameObject to select when you pick an object that the batch renders.</param>
    /// <param name="sceneCullingMask">Additional culling mask usually used for scene based culling. Additional resources: EditorSceneManager.GetSceneCullingMask.</param>
    /// <param name="renderingLayerMask">Rendering layer this batch will lives on. Additional resources: Renderer.renderingLayerMask.</param>
    /// <returns>
    ///   <para>The batch's index in the BatchedRendererGroup.</para>
    /// </returns>
    public int AddBatch(
      Mesh mesh,
      int subMeshIndex,
      Material material,
      int layer,
      ShadowCastingMode castShadows,
      bool receiveShadows,
      bool invertCulling,
      Bounds bounds,
      int instanceCount,
      MaterialPropertyBlock customProps,
      GameObject associatedSceneObject,
      ulong sceneCullingMask = 9223372036854775808,
      uint renderingLayerMask = 4294967295)
    {
      return this.AddBatch_Injected(mesh, subMeshIndex, material, layer, castShadows, receiveShadows, invertCulling, ref bounds, instanceCount, customProps, associatedSceneObject, sceneCullingMask, renderingLayerMask);
    }

    /// <summary>
    ///   <para>Sets flag bits that enable special behavior for this Hybrid Renderer V2 batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index. Must be a Hybrid Renderer V2 batch.</param>
    /// <param name="flags">Flag bits to set for the batch.</param>
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void SetBatchFlags(int batchIndex, ulong flags);

    public unsafe void SetBatchPropertyMetadata(
      int batchIndex,
      NativeArray<int> cbufferLengths,
      NativeArray<int> cbufferMetadata)
    {
      this.InternalSetBatchPropertyMetadata(batchIndex, (IntPtr) cbufferLengths.GetUnsafeReadOnlyPtr<int>(), cbufferLengths.Length, (IntPtr) cbufferMetadata.GetUnsafeReadOnlyPtr<int>(), cbufferMetadata.Length);
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void InternalSetBatchPropertyMetadata(
      int batchIndex,
      IntPtr cbufferLengths,
      int cbufferLengthsCount,
      IntPtr cbufferMetadata,
      int cbufferMetadataCount);

    /// <summary>
    ///   <para>Updates a batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="instanceCount">New number of instances in the batch.</param>
    /// <param name="customProps">Additional material properties to apply. See MaterialPropertyBlock.</param>
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void SetInstancingData(
      int batchIndex,
      int instanceCount,
      MaterialPropertyBlock customProps);

    /// <summary>
    ///   <para>Retrieves the matrices associated with one batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <returns>
    ///   <para>Matrices associated with the batch specified by batchIndex.</para>
    /// </returns>
    public unsafe NativeArray<Matrix4x4> GetBatchMatrices(int batchIndex)
    {
      int matrixCount = 0;
      NativeArray<Matrix4x4> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<Matrix4x4>(this.GetBatchMatrices(batchIndex, out matrixCount), matrixCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<Matrix4x4>(ref nativeArray, this.GetMatricesSafetyHandle(batchIndex));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced int properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable int properties for the batch specified by batchIndex.</para>
    /// </returns>
    public unsafe NativeArray<int> GetBatchScalarArrayInt(int batchIndex, string propertyName)
    {
      int elementCount = 0;
      NativeArray<int> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<int>(this.GetBatchScalarArray(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<int>(ref nativeArray, this.GetBatchArraySafetyHandle(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced float properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable float properties for the batch specified by batchIndex.</para>
    /// </returns>
    public unsafe NativeArray<float> GetBatchScalarArray(int batchIndex, string propertyName)
    {
      int elementCount = 0;
      NativeArray<float> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<float>(this.GetBatchScalarArray(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<float>(ref nativeArray, this.GetBatchArraySafetyHandle(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced int vector properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable vector properties for the batch specified by batchIndex, arranged linearly as individual int elements.</para>
    /// </returns>
    public unsafe NativeArray<int> GetBatchVectorArrayInt(int batchIndex, string propertyName)
    {
      int elementCount = 0;
      NativeArray<int> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<int>(this.GetBatchVectorArray(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<int>(ref nativeArray, this.GetBatchArraySafetyHandle(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced vector properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable vector properties for the batch specified by batchIndex.</para>
    /// </returns>
    public unsafe NativeArray<Vector4> GetBatchVectorArray(int batchIndex, string propertyName)
    {
      int elementCount = 0;
      NativeArray<Vector4> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<Vector4>(this.GetBatchVectorArray(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<Vector4>(ref nativeArray, this.GetBatchArraySafetyHandle(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced vector properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable matrix properties for the batch specified by batchIndex.</para>
    /// </returns>
    public unsafe NativeArray<Matrix4x4> GetBatchMatrixArray(int batchIndex, string propertyName)
    {
      int elementCount = 0;
      NativeArray<Matrix4x4> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<Matrix4x4>(this.GetBatchMatrixArray(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<Matrix4x4>(ref nativeArray, this.GetBatchArraySafetyHandle(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced int properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable int properties for the batch specified by batchIndex.</para>
    /// </returns>
    public unsafe NativeArray<int> GetBatchScalarArrayInt(int batchIndex, int propertyName)
    {
      int elementCount = 0;
      NativeArray<int> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<int>(this.GetBatchScalarArray_Internal(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<int>(ref nativeArray, this.GetBatchArraySafetyHandle_Int(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced float properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable float properties for the batch specified by batchIndex.</para>
    /// </returns>
    public unsafe NativeArray<float> GetBatchScalarArray(int batchIndex, int propertyName)
    {
      int elementCount = 0;
      NativeArray<float> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<float>(this.GetBatchScalarArray_Internal(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<float>(ref nativeArray, this.GetBatchArraySafetyHandle_Int(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced int vector properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable vector properties for the batch specified by batchIndex, arranged linearly as individual int elements.</para>
    /// </returns>
    public unsafe NativeArray<int> GetBatchVectorArrayInt(int batchIndex, int propertyName)
    {
      int elementCount = 0;
      NativeArray<int> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<int>(this.GetBatchVectorArray_Internal(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<int>(ref nativeArray, this.GetBatchArraySafetyHandle_Int(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced vector properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable vector properties for the batch specified by batchIndex.</para>
    /// </returns>
    public unsafe NativeArray<Vector4> GetBatchVectorArray(int batchIndex, int propertyName)
    {
      int elementCount = 0;
      NativeArray<Vector4> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<Vector4>(this.GetBatchVectorArray_Internal(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<Vector4>(ref nativeArray, this.GetBatchArraySafetyHandle_Int(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Retrieves an array of instanced vector properties for a given batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="propertyName">Property name.</param>
    /// <returns>
    ///   <para>An array of writable matrix properties for the batch specified by batchIndex.</para>
    /// </returns>
    public unsafe NativeArray<Matrix4x4> GetBatchMatrixArray(int batchIndex, int propertyName)
    {
      int elementCount = 0;
      NativeArray<Matrix4x4> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<Matrix4x4>(this.GetBatchMatrixArray_Internal(batchIndex, propertyName, out elementCount), elementCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<Matrix4x4>(ref nativeArray, this.GetBatchArraySafetyHandle_Int(batchIndex, propertyName));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Sets the bounding box of the batch.</para>
    /// </summary>
    /// <param name="batchIndex">Batch index.</param>
    /// <param name="bounds">The new bounds for the batch specified by batchIndex.</param>
    public void SetBatchBounds(int batchIndex, Bounds bounds)
    {
      this.SetBatchBounds_Injected(batchIndex, ref bounds);
    }

    /// <summary>
    ///   <para>Retrieves the number of batches added to the group.</para>
    /// </summary>
    /// <returns>
    ///   <para>Number of batches inside the group.</para>
    /// </returns>
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern int GetNumBatches();

    /// <summary>
    ///   <para>Removes a batch from the group.
    ///               Note: For performance reasons, the removal is done via emplace_back() which will simply replace the removed batch index with the last index in the array and will decrement the size.
    ///               If you're holding your own array of batch indices, you'll have to either regenerate it or apply the same emplace_back() mechanism as RemoveBatch does.</para>
    /// </summary>
    /// <param name="index">Batch index.</param>
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void RemoveBatch(int index);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern unsafe void* GetBatchMatrices(int batchIndex, out int matrixCount);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern unsafe void* GetBatchScalarArray(
      int batchIndex,
      string propertyName,
      out int elementCount);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern unsafe void* GetBatchVectorArray(
      int batchIndex,
      string propertyName,
      out int elementCount);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern unsafe void* GetBatchMatrixArray(
      int batchIndex,
      string propertyName,
      out int elementCount);

    [NativeName("GetBatchScalarArray")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern unsafe void* GetBatchScalarArray_Internal(
      int batchIndex,
      int propertyName,
      out int elementCount);

    [NativeName("GetBatchVectorArray")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern unsafe void* GetBatchVectorArray_Internal(
      int batchIndex,
      int propertyName,
      out int elementCount);

    [NativeName("GetBatchMatrixArray")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern unsafe void* GetBatchMatrixArray_Internal(
      int batchIndex,
      int propertyName,
      out int elementCount);

    private AtomicSafetyHandle GetMatricesSafetyHandle(int batchIndex)
    {
      AtomicSafetyHandle ret;
      this.GetMatricesSafetyHandle_Injected(batchIndex, out ret);
      return ret;
    }

    private AtomicSafetyHandle GetBatchArraySafetyHandle(int batchIndex, string propertyName)
    {
      AtomicSafetyHandle ret;
      this.GetBatchArraySafetyHandle_Injected(batchIndex, propertyName, out ret);
      return ret;
    }

    [NativeName("GetBatchArraySafetyHandle")]
    private AtomicSafetyHandle GetBatchArraySafetyHandle_Int(int batchIndex, int propertyName)
    {
      AtomicSafetyHandle ret;
      this.GetBatchArraySafetyHandle_Int_Injected(batchIndex, propertyName, out ret);
      return ret;
    }

    /// <summary>
    ///   <para>Enables or disables Rendering.BatchCullingContext.visibleIndicesY.</para>
    /// </summary>
    /// <param name="enabled">Pass true to enable the array, or false to disable it.</param>
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void EnableVisibleIndicesYArray(bool enabled);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern IntPtr Create(BatchRendererGroup group);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void Destroy(IntPtr groupHandle);

    [RequiredByNativeCode]
    private static unsafe void InvokeOnPerformCulling(
      BatchRendererGroup group,
      ref BatchRendererCullingOutput context,
      ref LODParameters lodParameters)
    {
      NativeArray<Plane> nativeArray1 = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<Plane>((void*) context.cullingPlanes, context.cullingPlanesCount, Allocator.Invalid);
      NativeArray<BatchVisibility> nativeArray2 = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<BatchVisibility>((void*) context.batchVisibility, context.batchVisibilityCount, Allocator.Invalid);
      NativeArray<int> nativeArray3 = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<int>((void*) context.visibleIndices, context.visibleIndicesCount, Allocator.Invalid);
      NativeArray<int> nativeArray4 = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<int>((void*) context.visibleIndicesY, context.visibleIndicesCount, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<Plane>(ref nativeArray1, AtomicSafetyHandle.Create());
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<BatchVisibility>(ref nativeArray2, AtomicSafetyHandle.Create());
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<int>(ref nativeArray3, AtomicSafetyHandle.Create());
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<int>(ref nativeArray4, AtomicSafetyHandle.Create());
      try
      {
        context.cullingJobsFence = group.m_PerformCulling(group, new BatchCullingContext(nativeArray1, nativeArray2, nativeArray3, nativeArray4, lodParameters, context.cullingMatrix, context.nearPlane));
      }
      finally
      {
        JobHandle.ScheduleBatchedJobs();
        AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle<Plane>(nativeArray1));
        AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle<BatchVisibility>(nativeArray2));
        AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle<int>(nativeArray3));
        AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle<int>(nativeArray4));
      }
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern int AddBatch_Injected(
      Mesh mesh,
      int subMeshIndex,
      Material material,
      int layer,
      ShadowCastingMode castShadows,
      bool receiveShadows,
      bool invertCulling,
      ref Bounds bounds,
      int instanceCount,
      MaterialPropertyBlock customProps,
      GameObject associatedSceneObject,
      ulong sceneCullingMask = 9223372036854775808,
      uint renderingLayerMask = 4294967295);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetBatchBounds_Injected(int batchIndex, ref Bounds bounds);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetMatricesSafetyHandle_Injected(int batchIndex, out AtomicSafetyHandle ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetBatchArraySafetyHandle_Injected(
      int batchIndex,
      string propertyName,
      out AtomicSafetyHandle ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetBatchArraySafetyHandle_Int_Injected(
      int batchIndex,
      int propertyName,
      out AtomicSafetyHandle ret);

    /// <summary>
    ///   <para>Culling callback function.</para>
    /// </summary>
    /// <param name="rendererGroup">Group to cull.</param>
    /// <param name="cullingContext">Culling context.</param>
    public delegate JobHandle OnPerformCulling(
      BatchRendererGroup rendererGroup,
      BatchCullingContext cullingContext);
  }
}
